package com.pkk.penguin.frame.know.java.interview.parampassing;

import org.junit.Test;

/**
 * @description: 字符串字面量测试
 * @author: peikunkun
 * @create: 2020-01-03 13:29
 **/
public class StringInternTests {

  @Test
  public void readme() {
    System.out.println("欢迎使用单元测试方法【Administrator_11()_20200103132921】");
    System.out.println("此方法测试描述：【字符串的字面量"
        + "1:字符串常量池是存在于(方法区/永久代)的一个字符串的池子"
        + "2:java字符串和其他对象一样,对象创建于堆中,而常量池只是保存堆中的地址引用"
        + "3:当编译阶段成class文件时,字符串和其他常量一样,会通过一种特殊的方式记录下来,当在加载阶段(最初阶段)JVM在class文件中寻找字符串字面量,当找到一个时,JVM会检查是否有相等的字符串在常量池中存放堆中的引用,找不到,则在堆中创建一个,然后把引用放到常量池(常量表中),一旦一个字符串被创建到常量池,程序中的所有该字符串都该给引用为常量池的引用"
        + "4:当我们通过new String()来创建对象时(运行时对象),则是在堆中创建了一个对象,和常量池的对象地址并不同"
        + "5:我们手动去掉对象的引用时,当执行GC操作时,这时堆中的字符串(存在常量池引用的对象)不会被回收,因为它还是存在常量池的引用】");
  }


  @Test
  public void Administrator_25_20200103134637() {
    System.out.println("欢迎使用单元测试方法【Administrator_25()_20200103134637】");
    System.out.println("此方法测试描述：【都是引用常量池的引用地址】");
    //常量池的字符串地址引用
    String msg = "hello";
    //常量池的字符串地址引用
    String msg1 = "hello";
    System.out.println(msg.equals(msg1));
    System.out.println(msg == msg1);
  }

  @Test
  public void Administrator_35_20200103134731() {
    System.out.println("欢迎使用单元测试方法【Administrator_35()_20200103134731】");
    System.out.println("此方法测试描述：【】");
    //常量池的字符串地址引用
    String msg = "hello";
    //堆中字符串的地址引用
    String msg1 = new String("hello");
    System.out.println(msg.equals(msg1));
    System.out.println(msg == msg1);
  }

  @Test
  public void Administrator_47_20200103134834() {
    System.out.println("欢迎使用单元测试方法【Administrator_47()_20200103134834】");
    System.out.println("此方法测试描述：【】");

    //常量池的字符串地址引用
    String msg = "hello";
    //堆中字符串的地址引用
    String msg1 = new String("hello");
    System.out.println(msg.equals(msg1));
    //常量池的字符串地址引用
    final String msg1Temp = msg1.intern();
    System.out.println(msg == msg1);
    System.out.println(msg == msg1Temp);
  }

  @Test
  public void Administrator_65_20200103135017() {
    System.out.println("欢迎使用单元测试方法【Administrator_65()_20200103135017】");
    System.out.println("此方法测试描述：【】");
    //常量池的字符串地址引用
    String msg = "hello";
    //堆中字符串的地址引用
    String msg1 = new String("hello");
    //msg清除必要引用
    msg = msg1 = null;
    System.out.println(msg);
    System.out.println(msg1);
    System.out.println("执行垃圾回收时,堆中的对象不会被回收,因为常量池会存在堆中的地址引用");
  }


}
